package br.usp.ime.ingpos.modelo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.Fetch;

@Entity
public class Inscricao
    implements
        Serializable
{
    private static final long serialVersionUID = 2908521459850511244L;

    @Id
    @GeneratedValue
    private Long inscricaoID;

    @Column
    private String outrosProcessosSeletivos;

    @Column
    private String dedicacaoExclusiva;

    @Column( length = 1000 )
    private String exposicaoPropositos;

    @Column( length = 1000 )
    private String observacoes;
    
    @Column
    private String bolsaNoIme;
    
    @Column
    private String pedidoDeBolsaNaInstituicao;

    @ManyToOne
    @JoinColumn(nullable = false)
    private ProcessoSeletivo processoSeletivo;

    @ManyToOne( fetch = FetchType.EAGER )
    @JoinColumn( name = "usuarioID" )
    private Candidato candidato;

    @ManyToOne
    private Orientador orientadorDesejado;
    
    @OneToOne
    private Orientador orientadorAtribuido;

    @Column( columnDefinition = "BOOLEAN" )
    private boolean sabeAreasDeInteresse = true;

    @Column( columnDefinition = "BOOLEAN" )
    private boolean aprovado = false;

    @Column( columnDefinition = "BOOLEAN" )
    private boolean conversouComCoordenador = false;

    @ManyToMany
    @JoinTable( name = "Inscricao_AreasDeInteresseAfinidade1", joinColumns = {
        @JoinColumn( referencedColumnName = "inscricaoID" )
    } )
    private List<AreaDePesquisa> areasDeInteresseAfinidade1 = new ArrayList<AreaDePesquisa>();

    @ManyToMany
    @JoinTable( name = "Inscricao_AreasDeInteresseAfinidade2", joinColumns = {
        @JoinColumn( referencedColumnName = "inscricaoID" )
    } )
    private List<AreaDePesquisa> areasDeInteresseAfinidade2 = new ArrayList<AreaDePesquisa>();

    @ManyToMany
    @JoinTable( name = "Inscricao_AreasDeInteresseAfinidade3", joinColumns = {
        @JoinColumn( referencedColumnName = "inscricaoID" )
    } )
    private List<AreaDePesquisa> areasDeInteresseAfinidade3 = new ArrayList<AreaDePesquisa>();

    @OneToMany
    @Cascade( {
        CascadeType.ALL
    } )
    private Set<CartaDeRecomendacao> cartasDeRecomendacao;
    
    private boolean inscricaoFinalizada;

	public Inscricao()
    {
        setOrientadorAtribuido( null );
    }
    
    public Candidato getCandidato()
    {
        return candidato;
    }

    public void setCandidato(
        Candidato candidato )
    {
        this.candidato = candidato;
    }

    public Long getInscricaoID()
    {
        return inscricaoID;
    }

    public void setInscricaoID(
        Long inscricaoID )
    {
        this.inscricaoID = inscricaoID;
    }

    public ProcessoSeletivo getProcessoSeletivo()
    {
        return processoSeletivo;
    }

    public void setProcessoSeletivo(
        ProcessoSeletivo processoSeletivo )
    {
        this.processoSeletivo = processoSeletivo;
    }

    public String getOutrosProcessosSeletivos()
    {
        return outrosProcessosSeletivos;
    }

    public void setOutrosProcessosSeletivos(
        String outrosProcessosSeletivos )
    {
        this.outrosProcessosSeletivos = outrosProcessosSeletivos;
    }

    public Orientador getOrientadorDesejado()
    {
        return orientadorDesejado;
    }

    public void setOrientadorDesejado(
        Orientador orientadorDesejado )
    {
        this.orientadorDesejado = orientadorDesejado;
    }

    public String getDedicacaoExclusiva()
    {
        return dedicacaoExclusiva;
    }

    public void setDedicacaoExclusiva(
        String dedicacaoExclusiva )
    {
        this.dedicacaoExclusiva = dedicacaoExclusiva;
    }

    public static long getSerialversionuid()
    {
        return serialVersionUID;
    }

    public List<AreaDePesquisa> getAreasDeInteresseAfinidade1()
    {
        return areasDeInteresseAfinidade1;
    }

    public void setAreasDeInteresseAfinidade1(
        List<AreaDePesquisa> areasDeInteresseAfinidade1 )
    {
        this.areasDeInteresseAfinidade1 = areasDeInteresseAfinidade1;
    }

    public List<AreaDePesquisa> getAreasDeInteresseAfinidade2()
    {
        return areasDeInteresseAfinidade2;
    }

    public void setAreasDeInteresseAfinidade2(
        List<AreaDePesquisa> areasDeInteresseAfinidade2 )
    {
        this.areasDeInteresseAfinidade2 = areasDeInteresseAfinidade2;
    }

    public List<AreaDePesquisa> getAreasDeInteresseAfinidade3()
    {
        return areasDeInteresseAfinidade3;
    }

    public void setAreasDeInteresseAfinidade3(
        List<AreaDePesquisa> areasDeInteresseAfinidade3 )
    {
        this.areasDeInteresseAfinidade3 = areasDeInteresseAfinidade3;
    }

    public String getExposicaoPropositos()
    {
        return exposicaoPropositos;
    }

    public void setExposicaoPropositos(
        String exposicaoPropositos )
    {
        this.exposicaoPropositos = exposicaoPropositos;
    }

    public String getObservacoes()
    {
        return observacoes;
    }

    public void setObservacoes(
        String observacoes )
    {
        this.observacoes = observacoes;
    }

    @Override
    public boolean equals(
        Object obj )
    {
        if( this == obj ) {
            return true;
        }
        if( ! obj.getClass().equals( this.getClass() ) ) {
            return false;
        }

        Inscricao inscricao = (Inscricao) obj;

        if( inscricaoID != null ) {
            return inscricaoID.equals( inscricao.getInscricaoID() );
        } else {
            return super.equals( obj );
        }
    }

    @Override
    public int hashCode()
    {
        if( inscricaoID != null ) {
            return inscricaoID.hashCode();
        } else {
            return super.hashCode();
        }
    }

    public void setSabeAreasDeInteresse(
        boolean sabeAreasDeInteresse )
    {
        this.sabeAreasDeInteresse = sabeAreasDeInteresse;
    }

    public boolean isSabeAreasDeInteresse()
    {
        return sabeAreasDeInteresse;
    }

    public void setCartasDeRecomendacao(
        Set<CartaDeRecomendacao> cartasDeRecomendacao )
    {
        this.cartasDeRecomendacao = cartasDeRecomendacao;
    }

    public Set<CartaDeRecomendacao> getCartasDeRecomendacao()
    {
        return cartasDeRecomendacao;
    }

    public void setAprovado(
        boolean aprovado )
    {
        this.aprovado = aprovado;
    }

    public boolean isAprovado()
    {
        return aprovado;
    }
    
    public boolean isConversouComCoordenador()
    {
        return conversouComCoordenador;
    }

    public void setConversouComCoordenador(
        boolean conversouComCoordenador )
    {
        this.conversouComCoordenador = conversouComCoordenador;
    }

    public void setOrientadorAtribuido(
        Orientador orientadorAtribuido )
    {
        this.orientadorAtribuido = orientadorAtribuido;
    }

    public Orientador getOrientadorAtribuido()
    {
        return orientadorAtribuido;
    }
    
    // Isso devera virar, de alguma forma magica, o valor inicial
    // do checkbox em listaCandidatos.jsp (checked/unchecked)
    public boolean isInteresse()
    {
    	return false;
    }

    public void setInscricaoFinalizada(
        boolean inscricaoFinalizada )
    {
        this.inscricaoFinalizada = inscricaoFinalizada;
    }

    public boolean isInscricaoFinalizada()
    {
        return inscricaoFinalizada;
    }
    
    public String getBolsaNoIme()
    {
        return bolsaNoIme;
    }

    public void setBolsaNoIme(
        String bolsaNoIme )
    {
        this.bolsaNoIme = bolsaNoIme;
    }

    public String getPedidoDeBolsaNaInstituicao()
    {
        return pedidoDeBolsaNaInstituicao;
    }

    public void setPedidoDeBolsaNaInstituicao(
        String pedidoDeBolsaNaInstituicao )
    {
        this.pedidoDeBolsaNaInstituicao = pedidoDeBolsaNaInstituicao;
    }
}
